package org.springframework.security.config.annotation;

import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @author Dillon
 * @date 2024/7/4
 * @slogan 致敬大师 致敬未来的你
 * @desc security 构建接口的抽象方法，构建并缓存已构建的对象
 */
public abstract class AbstractSecurityBuilder<O> implements SecurityBuilder<O> {

	/**
	 * 原子方法，确保类只能被构建一次
	 */
	private final AtomicBoolean building = new AtomicBoolean();

	/**
	 * 已构建的对象
	 */
	private O object;

	/**
	 * 构建接口，用于构建对象
	 *
	 * @return 已构建完成的对象
	 * @throws Exception 执行异常
	 */
	@Override
	public final O build() throws Exception {
		if (this.building.compareAndSet(false, true)) {
			this.object = doBuild();
			return this.object;
		}
		throw new AlreadyBuiltException("当前对象已构建");
	}

	/**
	 * 获取已构建完成的对象
	 *
	 * @return 构建完成对象
	 */
	public final O getObject() {
		if (!this.building.get()) {
			throw new IllegalStateException("当前对象还未构建");
		}
		return this.object;
	}

	/**
	 * 抽象方法，执行构建
	 *
	 * @return 构建完成的对象
	 * @throws Exception 执行异常
	 */
	protected abstract O doBuild() throws Exception;

}
